Android — SwipeRefreshLayout 下拉刷新上拉加载

前言

总感觉我好像写过下拉刷新,用的是隐藏的头布局,ListView.addHeaderView(),监听手势下拉显示出来,emmmm,记得当时写的很辣鸡。

今天给大家介绍 的SwipeRefreshLayout 是 Google 提供的下拉刷新控件,试了一下,还是蛮好用的耶。不过可惜的是只有下拉刷新,没有上拉加载。那就写一个下拉加载,效果如下:

布局

首先要弄清楚,SwipeRefreshLayout 和之前讲的 TextInputLayout 其实都是相当于一个容器,里面只能放一个子控件。SwipeRefreshLayout 里面放的子控件必须是可以滑动的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swipeRefresh"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent">
</ListView>
</android.support.v4.widget.SwipeRefreshLayout>
</LinearLayout>

属性

1
2
3
4
5
6
7
mSwipeRefreshLayout = findViewById(swipeRefresh);
//设置下拉进度条颜色
mSwipeRefreshLayout.setColorSchemeColors(getResources().getColor(R.color.refresh));
//设置下拉进度条的背景颜色,默认白色
// mSwipeRefreshLayout.setProgressBackgroundColorSchemeColor(getResources().getColor(R.color.refreshbackground));
//设置监听
mSwipeRefreshLayout.setOnRefreshListener(this);

代码

需要该 Activity 实现 SwipeRefreshLayout.OnRefreshListener 的接口,重写 onRefresh() 方法。该方法是在刷新结束后自动调用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public void onRefresh() {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
for (int i=0;i<5;i++) {
mListItems.remove(i);
mListItems.add(new ListItem("下拉刷新后的第 " + i + " 条数据"));
}
mAdapter.notifyDataSetChanged();
//取消刷新状态
mSwipeRefreshLayout.setRefreshing(false);
Toast.makeText(SwipeRefresh.this, "刷新了五条数据", Toast.LENGTH_SHORT).show();
}
}, 1200);
}

以上就实现了下拉刷新的功能,下面开始实现上拉加载。

上拉加载

思路就是判断滑动的最后一项 item 是总共 item -1 ,然后ListView 的 addFooterView() 方法给下拉状态状态加载一个布局。

foot_view:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:gravity="center"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:id="@+id/foot_view"
android:layout_height="50dp">
<ProgressBar
style="@android:style/Widget.ProgressBar.Small"
android:layout_width="20dp"
android:layout_height="20dp" />
<TextView
android:layout_marginLeft="10dp"
android:textSize="20sp"
android:text="正在加载..."
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>

代码:

实现 AbsListView.OnScrollListener() 接口,重写两个接口方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
@Override
public void onScrollStateChanged(AbsListView absListView, int i) {
int lastVisibleIndex = absListView.getLastVisiblePosition();
Log.i("2333", lastVisibleIndex + "");
if (!mIsLoading && i == AbsListView.OnScrollListener.SCROLL_STATE_IDLE && lastVisibleIndex == mTotalItemCount - 1) {
mIsLoading = true;
mListView.addFooterView(mFootView);
Toast.makeText(this, "滑动到底部了", Toast.LENGTH_SHORT).show();
loadMore();
}
}
@Override
public void onScroll(AbsListView absListView, int i, int i1, int i2) {
mTotalItemCount = i2;
}
private void loadMore() {
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000);
runOnUiThread(new Runnable() {
@Override
public void run() {
for (int i=0;i<5;i++) {
mListItems.add(new ListItem("上拉加载后的第 "+i+" 条数据"));
}
mAdapter.notifyDataSetChanged();
mListView.removeFooterView(mFootView);
mIsLoading = false;
}
});
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}

参考:

http://www.jianshu.com/p/b502c5b59998
http://www.jianshu.com/p/c1c4512ef7f7

最后

还有上次的 TextInputLayout 控件的使用 以及这次的 SwipeRefreshLayout 的使用源码都放在 –> https://github.com/Omooo/TestLogin <– 这了,不定时更新新的实用的空间。

我们一直都向往,面朝大海,春暖花开。 但是几人能做到,心中有爱,四季不败?